package com.cgah

import com.cgah.exceptions.BidNotFoundException
import javax.jws.WebMethod
import javax.jws.WebResult
import javax.jws.WebParam

class BidService {//implements com.cgah.api.BidService {
    static expose=['cxfjax']
    static transactional = true
    def emailService

    def checkListingExpiration(def params) {
        def listingId = params.'listing.id'

        def listing = params.listing;
        def listingEndDateTime = null;
        if (listing) {
            if (listing instanceof Listing) {
                listingEndDateTime = listing.endDateTime;
            }
        }
        if (!listingEndDateTime) {
            if (listingId) {
                listing = Listing.get(listingId)
                if (listing) {
                    listingEndDateTime = listing.endDateTime;
                }
              }
        }

        if (!listingEndDateTime) {
            throw new  BidNotFoundException("Cannot save bid listing not found.");
        }

        if (listingEndDateTime.before(new Date())) {
            throw new  BidNotFoundException("Cannot save bid.  Listing has expired");
        }
    }

    def countOfBids() {
        return Bid.count()
    }



/*
    @WebResult(name="Bid")
    @WebMethod(operationName="create")
*/
    def create(def params) {
        //checkListingExpiration
        def bidInstance = new Bid()
        bidInstance.properties = params
        return bidInstance;
    }


    def list(def params, def userName, def password) {
        def user = UserUtil.getUser(userName, password);
        if (user) {
            return list(params);
        } else {
            log.error("failed to get user for username and password, (" + userName + ", " + password + ")")
            throw new BidNotFoundException("Cannot list bids");
        }

    }

    def list(def params) {
        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        return Bid.list(params)
    }


    // W-3: Expose the three Grails service methods created for S-1, S-2, and S-3 via SOAP/WSD
    @WebResult(name="Bid")
    @WebMethod(operationName="save")
    Bid save(@WebParam(name="bid") Bid bid, String userName, String password) {

        if (bid.dateTime.after(bid.listing.endDateTime)) {
            throw new  BidNotFoundException("Cannot save bid after listing has expired.");
        }

        def user = UserUtil.getUser(userName, password);
        if (user) {
            bid.customer = user
            bid = bid.save(flush:true)

            try {
                if (bid) {
                    emailService.sendBidSuccessEmail(bid, String.valueOf(bid.listing.id))
                }
            } catch (Exception e) {
                log.error(e);
            }
            return bid //save(params, user.id);
        } else {
            log.error("failed to get user for username and password, (" + userName + ", " + password + ")")
            throw new BidNotFoundException("Cannot save bid");
        }
    }



    def save(def params, def userId) {
        checkListingExpiration(params);
        params.'customer.id' = userId;
        def bid  = new Bid(params).save(flush: true)
        try {
            if (bid) {
                emailService.sendBidSuccessEmail(bid, bid.listing.id)
            }

        } catch (Exception e) {
            log.error(e);
        }

        return bid
    }


    def getBidById(def id, def userName, def password) {
        def user = UserUtil.getUser(userName, password);
        if (user) {
            return getBidById(id);
        } else {
            log.error("failed to get user for username and password, (" + userName + ", " + password + ")")
            throw new BidNotFoundException("Cannot get Bid By Id: " + id);
        }

    }


    def getBidById(def id) throws BidNotFoundException {
        def bidInstance = Bid.get(id)
        if (null == bidInstance) {
            throw new BidNotFoundException("Bid with id: " + id + " does not exists.");
        }
        return bidInstance;
    }



    def updateBidWithParams(def params, def userName, def password) {
        def user = UserUtil.getUser(userName, password);
        if (user) {
            return updateBidWithParams(params);
        } else {
            log.error("failed to get user for username and password, (" + userName + ", " + password + ")")
            throw new BidNotFoundException("Cannot update bid: " + id);
        }
    }


    def updateBidWithParams(def params) throws BidNotFoundException {
        def bidInstance = this.getBidById(params.id)
        if (bidInstance) {
            if (params.version && bidInstance.version > params.version.toLong()) {
                bidInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'bid.label', default: 'Bid')] as Object[], "Another user has updated this Bid while you were editing")
            } else {
                bidInstance.properties = params
                if (!bidInstance.hasErrors()) {
                    this.save(bidInstance, userId)
                }
            }
        }
        return bidInstance;
    }

    def deleteBidById(def id, def userName, def password) throws BidNotFoundException {
        def user = UserUtil.getUser(userName, password);
        if (user) {
            return deleteBidById(id);
        } else {
            log.error("failed to get user for username and password, (" + userName + ", " + password + ")")
            throw new BidNotFoundException("Cannot delete bid: " + id);
        }
    }

    def deleteBidById(def id) throws BidNotFoundException {
        def bidInstance = this.getBidById(id)
        bidInstance.delete(flush: true)
    }

}

